package erp

import (
	"context"
	"encoding/json"
	"strconv"
	"strings"

	"mall/common/moneyx"
	"mall/common/utils/pointy"
	"mall/service/backend/api/internal/logic/backend/util"
	"mall/service/backend/api/internal/svc"
	"mall/service/backend/api/internal/types"
	"mall/service/backend/common/erp"
	"mall/service/order/rpc/orderclient"

	// "github.com/sirupsen/logrus"
	"github.com/friendsofgo/errors"
	"github.com/zeromicro/go-zero/core/logx"
)

type PushAfterSaleOrderToErpLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

// 售后单推送
// todo:自有商城无法使用售后单
func NewPushAfterSaleOrderToErpLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PushAfterSaleOrderToErpLogic {
	return &PushAfterSaleOrderToErpLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *PushAfterSaleOrderToErpLogic) PushAfterSaleOrderToErp(req *types.PushOrderToErpReq) (resp *types.BaseMsgResp, err error) {
	if req.Id != nil && *req.Id > 0 {
		queryMaps, err := l.getAfterSale(*req.Id)
		if err != nil {
			return nil, err
		}
		// 文档地址：https://open.hupun.com/api-doc/erp/b2c/refunds/open
		if err = l.pushOrderToErp(queryMaps); err != nil {
			return nil, err
		}
	}

	return &types.BaseMsgResp{
		Success: true,
		Msg:     "推送售后订单至ERP成功", // 售后订单推送
		// Msg:     l.svcCtx.Trans.Trans(l.ctx, res.Msg),
	}, nil
}

func (l *PushAfterSaleOrderToErpLogic) getAfterSale(id uint64) (map[string]string, error) {
	data, err := l.svcCtx.OrderRpc.BackendGetAfterSaleById(l.ctx, &orderclient.AfterSaleIdReq{
		Id:          id,
		WithAddress: pointy.GetPointer(uint32(1)),
	})
	if err != nil {
		logx.Errorw("PushAfterSaleOrderToErp getAfterSale OrderRpc.BackendGetAfterSaleList err", logx.Field("detail", err.Error()))
		return nil, err
	}

	if data != nil && data.Id != nil && *data.Id > 0 {
		var buyer string
		if data.NickName != nil && len(*data.NickName) > 0 {
			buyer = *data.NickName
		}
		var createdAt string
		if data.CreatedAt != nil {
			createdAt = *data.CreatedAt
		}
		var endedAt string
		if data.EndedAt != nil {
			endedAt = *data.EndedAt
		}
		var expressCode string
		if data.ExpressSn != nil {
			expressCode = *data.ExpressSn
		}
		var orderSn string
		var parcelSn string
		var productId string
		var productSkuId string
		var quantity uint32
		if data.OrderSn != nil {
			orderSn = *data.OrderSn
		}
		if data.ProductId != nil {
			productId = strconv.FormatUint(*data.ProductId, 10)
		}
		if data.ProductSkuId != nil {
			productSkuId = strconv.FormatUint(*data.ProductSkuId, 10)
		}
		if data.Quantity != nil {
			quantity = *data.Quantity
		}
		if data.OrderItemId != nil {
			parcelSn = orderSn + "_" + strconv.FormatUint(*data.OrderItemId, 10)
		}
		items := []map[string]any{{
			"order_id":       parcelSn,     // 子交易单号 退回的订单明细id  string
			"change_item_id": productId,    // 换货商品item_id关联原单销售订单(需要商品有对应关系）type=3时使用  string
			"change_num":     quantity,     // 换出商品数量，changeItemID和changeSkuID都为空时候代表退回商品和换出商品一致 type=3时使用  integer
			"change_sku_id":  productSkuId, // 换货商品sku_id关联原单销售订单(需要商品有对应关系） type=3时使用  string
		}}
		var logisticsName string
		if data.LogisticName != nil {
			logisticsName = *data.LogisticName
		}
		var updatedAt string
		if data.UpdatedAt != nil {
			updatedAt = *data.UpdatedAt
		}
		var reason string
		if data.Remark != nil {
			reason = *data.Remark
		}
		var receiver map[string]any
		if len(data.Addresses) > 0 {
			address := data.Addresses[0]
			var detailedAddress string
			var district string
			var city string
			var mobile string
			var consignee string
			var province string
			if address != nil {
				if address.Address != nil && len(strings.TrimSpace(*address.Address)) > 0 {
					detailedAddress = strings.TrimSpace(*address.Address)
				}
				if address.District != nil && len(strings.TrimSpace(*address.District)) > 0 {
					district = *address.District
				}
				if address.City != nil && len(strings.TrimSpace(*address.City)) > 0 {
					city = *address.City
				}
				if address.Mobile != nil && len(strings.TrimSpace(*address.Mobile)) > 0 {
					mobile = *address.Mobile
				}
				if address.Consignee != nil && len(strings.TrimSpace(*address.Consignee)) > 0 {
					consignee = *address.Consignee
				}
				if address.Province != nil && len(strings.TrimSpace(*address.Province)) > 0 {
					province = *address.Province
				}
				receiver = map[string]any{
					"receiver_address":  detailedAddress, // 详细地址  string
					"receiver_area":     district,        // 区  string
					"receiver_city":     city,            // 市  string
					"receiver_mobile":   mobile,          // 收件人手机  string
					"receiver_name":     consignee,       // 收件人  string
					"receiver_province": province,        // 省  string
				}
			}
		}
		var afterSaleAmount float64
		if data.RefundAmount != nil && len(*data.RefundAmount) > 0 {
			if f, err := moneyx.ParseAmountToFloat(*data.RefundAmount); err == nil {
				afterSaleAmount = f
			}
		}
		var refundCode string
		if data.AfterSaleSn != nil {
			refundCode = *data.AfterSaleSn
		}
		var status uint32
		if data.Status != nil {
			status = util.OrderRefundStatusToErpOrderStatus(data.Status)
		}
		var afterSaleType uint32
		if data.AfterSaleType != nil {
			afterSaleType = *data.AfterSaleType
		}

		// 参考文档： https://open.hupun.com/api-doc/erp/b2c/refunds/open
		refund := map[string]any{
			"buyer":          buyer,                        // 买家昵称  string
			"create":         createdAt,                    // 创建时间  string<date-time>
			"end_time":       endedAt,                      // 完成时间  string<date-time>
			"express_code":   expressCode,                  // 退货快递单号  string
			"items":          items,                        // 退换货明细  array[object]
			"logistics_name": logisticsName,                // 物流公司 string
			"modified":       updatedAt,                    // 修改时间  string<date-time>
			"reason":         reason,                       // 售后原因  string
			"receiver":       receiver,                     // 收件人信息  object
			"refund_fee":     afterSaleAmount,              // 售后金额  number
			"refund_id":      refundCode,                   // 售后单号（不能为空）  string
			"shop_nick":      l.svcCtx.Config.Erp.ShopNick, // 在ERP中注册的卖家（店铺）昵称（不能为空）  string
			"status":         status,                       // 售后单状态:1: 换货待处理 2: 待买家退货 3: 买家已退货，待收货 4: 待买家修改 5: 换货关闭 6: 换货成功 7: 待发出换货商品（不能为空）  integer
			"trade_id":       orderSn,                      // 第三方交易号（不能为空）  string
			"type":           afterSaleType,                // 售后类型: 1:仅退款 2:退货 3:换货（不能为空）  integer
		}

		logx.Infof("PushAfterSaleOrderToErp getAfterSale refund: %+v ", refund)
		//[map[buyer:ed.蔡 buyer_message: create_time:2025-05-29 17:36:59 discount_fee:0 end_time: has_refund:1 modify_time:2025-05-29 18:07:00 orders:[map[has_refund:1 image_url:https://static.scentrobe.com/uploads/202307/77f99fd69e2b459a48dab6af2c02a29c.jpg item_code: item_id:7 item_title:神话女士 payment:0 price:8 size:1 sku_code:669632558 sku_id:93 sku_title:1ml status:0 trade_id:O20250529173658539827001]] pay_no:PMT20250529173658539827001 pay_time: pay_type:微信支付 payment:0.02 post_fee:10 print_config:实物订单 receiver_address:凤舞路30(北辰三角洲地铁站3号口步行280米) 开福城投大厦 receiver_area:开福区 receiver_city:长沙市 receiver_mobile:18588998859 receiver_name:徐小姐 receiver_province:湖南省 receiver_zip: seller_memo: shipping_time: shop_nick:shop1820 status:0 total_fee:10.01 trade_id:O20250529173658539827001 trade_type:1]]

		item, err := json.Marshal(refund)
		if err != nil {
			logx.Errorw("PushAfterSaleOrderToErp getAfterSale json.Marshal err", logx.Field("detail", err.Error()))
			return nil, err
		}

		return map[string]string{
			"refund": string(item),
		}, nil
	}

	return nil, nil
}

func (l *PushAfterSaleOrderToErpLogic) pushOrderToErp(queryMap map[string]string) error {
	if queryMap != nil {
		// logx.Infof("PushAfterSaleOrderToErp queryMap : %+v ", queryMap)
		path := "/erp/b2c/refunds/open"
		erpClient := erp.NewErp(l.svcCtx.Config.Erp.AppKey, l.svcCtx.Config.Erp.Secret, l.svcCtx.Config.Erp.Url, path)
		err := erpClient.GetSign(queryMap)
		if err != nil {
			logx.Errorw("PushAfterSaleOrderToErp GetSign err", logx.Field("detail", err.Error()))
			return err
		}

		resMap, err := erpClient.CallErpApi()
		if err != nil {
			logx.Errorw("PushAfterSaleOrderToErp CallErpApi err", logx.Field("detail", err.Error()))
			return err
		}
		// logx.Infof("PushAfterSaleOrderToErp response : %+v ", resMap)
		// map[response:[\"O20250529173658539827001\"] success:true]
		if !resMap["success"].(bool) {
			return errors.New(resMap["error_msg"].(string))
		}
	}

	return nil
}
